# utils.py
# from functools import wraps
# from basic import models as basic_models
# from django.db.models import Q
#
# def with_oracle_instanceinfo(view_func):
#     """装饰器：为视图函数注入 Oracle 实例信息"""
#     @wraps(view_func)
#     def wrapper(request, *args, **kwargs):
#         instanceinfo_result = basic_models.instance_info.objects.filter(
#             ~Q(status='LOCKED'),
#             db_type='ORACLE'
#         ).order_by('id')
#         instanceinfo_result_total = len(instanceinfo_result)
#
#         # 把查询结果放进 kwargs，这样视图函数直接用
#         kwargs['instanceinfo_result'] = instanceinfo_result
#         kwargs['instanceinfo_result_total'] = instanceinfo_result_total
#
#         return view_func(request, *args, **kwargs)
#     return wrapper


# utils.py
from functools import wraps
from django.http import HttpResponseNotAllowed
from django.db.models import Q
from basic import models as basic_models

def with_instanceinfo(
    db_type='ORACLE',
    allowed_methods=('GET',),
    include_db_types=('ORACLE', 'MYSQL', 'POSTGRESQL', 'MONGODB'),
    extra_filters=None,
    extra_excludes=None,
    order_by=('id',),
    exclude_status='LOCKED',
):
    """
    通用装饰器：为视图函数注入实例信息查询结果与总数。

    参数：
    - db_type: str | 'ALL'           指定单一类型或 'ALL'（使用 include_db_types）
    - allowed_methods: tuple         限制允许的 HTTP 方法（默认只允许 GET）
    - include_db_types: iterable     当 db_type='ALL' 时使用的类型集合
    - extra_filters: dict            追加 filter 条件（如 {'env': 'prod'}）
    - extra_excludes: dict           追加 exclude 条件
    - order_by: tuple                排序字段（默认按 id 升序）
    - exclude_status: str            排除的状态（默认 'LOCKED'）

    视图函数会额外收到：
    - instanceinfo_result: QuerySet
    - instanceinfo_result_total: int
    """
    extra_filters = extra_filters or {}
    extra_excludes = extra_excludes or {}

    def decorator(view_func):
        @wraps(view_func)
        def wrapper(request, *args, **kwargs):
            # 1) 方法限制
            if allowed_methods and request.method not in allowed_methods:
                return HttpResponseNotAllowed(allowed_methods)

            # 2) 基础查询
            qs = basic_models.instance_info.objects.filter(~Q(status=exclude_status))

            # 3) 类型过滤
            if db_type == 'ALL':
                qs = qs.filter(db_type__in=include_db_types)
            else:
                # 不区分大小写更稳
                qs = qs.filter(db_type__iexact=db_type)

            # 4) 追加筛选
            if extra_filters:
                qs = qs.filter(**extra_filters)
            if extra_excludes:
                qs = qs.exclude(**extra_excludes)

            # 5) 排序
            if order_by:
                qs = qs.order_by(*order_by)

            # 6) 统计（count 不会把数据全取出来）
            total = qs.count()

            # 7) 注入到视图参数
            kwargs['instanceinfo_result'] = qs
            kwargs['instanceinfo_result_total'] = total

            return view_func(request, *args, **kwargs)
        return wrapper
    return decorator
